/*
 * Copyright (c) 2023-2025 elsfs Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.elsfs.cloud.module.ai.biz.controller;

import dev.langchain4j.community.model.dashscope.QwenStreamingChatModel;
import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.chat.response.ChatResponse;
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
import dev.langchain4j.model.ollama.OllamaStreamingChatModel;
import dev.langchain4j.store.embedding.EmbeddingStore;
import jakarta.servlet.http.HttpServletResponse;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.elsfs.cloud.module.ai.biz.service.Assistant;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

/**
 * ai 聊天
 *
 * @author zeng
 */
@Slf4j
@RequestMapping("/ai")
@RequiredArgsConstructor
@RestController
public class AiChatController {

  private final ChatLanguageModel chatLanguageModel;
  private final EmbeddingStore<TextSegment> embeddingStore;
  private final QwenStreamingChatModel qwenStreamingChatModel;
  private final Assistant assistant;

  /**
   * 聊天
   *
   * @param userMessage 聊天
   * @return 聊天
   */
  @GetMapping("/chat")
  public String chat(@RequestParam("msg") String userMessage) {
    return assistant.chatString("1", userMessage);
  }

  /**
   * 流式返回
   *
   * @param request request
   * @param response response
   * @return s
   */
  @PostMapping(
      value = "/stream",
      produces = MediaType.TEXT_EVENT_STREAM_VALUE,
      consumes = MediaType.APPLICATION_JSON_VALUE)
  public Flux<String> streamChat(
      @RequestBody StreamChatRequest request, HttpServletResponse response) {

    response.setCharacterEncoding("UTF-8");

    UserMessage userMessage = UserMessage.from(request.message());

    List<ChatMessage> messages = List.of(userMessage);

    OllamaStreamingChatModel chatModel =
        OllamaStreamingChatModel.builder().modelName("deepseek-r1:1.5b").build();

    return Flux.create(
        sink -> {
          chatModel.chat(
              messages,
              new StreamingChatResponseHandler() {
                @Override
                public void onPartialResponse(String partialResponse) {
                  sink.next(partialResponse);
                  // data:需要帮助，欢迎
                  //
                  // data:随时向我提问！
                }

                @Override
                public void onCompleteResponse(ChatResponse completeResponse) {
                  //                    log.info("complete:{}", completeResponse);
                  sink.next("[DONE]");
                  sink.complete();
                }

                @Override
                public void onError(Throwable error) {
                  sink.error(error);
                }
              });
        });
  }

  /**
   * 请求
   *
   * @param userId userId
   * @param message message
   */
  public record StreamChatRequest(String userId, String message) {}
}
